<template>
  <div class="model-evaluation">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-content">
        <h1 class="page-title">模型评估</h1>
        <p class="page-description">评估模型性能，查看详细的评估指标和可视化结果</p>
      </div>
      <div class="header-actions">
        <el-button type="primary" @click="runEvaluation">
          <el-icon><VideoPlay /></el-icon>
          运行评估
        </el-button>
        <el-button @click="exportReport">
          <el-icon><Download /></el-icon>
          导出报告
        </el-button>
      </div>
    </div>

    <!-- 模型选择 -->
    <div class="model-selection">
      <el-card>
        <template #header>
          <span>选择评估模型</span>
        </template>
        <div class="selection-content">
          <div class="model-selector">
            <el-select 
              v-model="selectedModelId" 
              placeholder="选择要评估的模型"
              @change="handleModelChange"
              style="width: 300px"
            >
              <el-option 
                v-for="model in availableModels" 
                :key="model.id"
                :label="model.name" 
                :value="model.id"
              >
                <div class="model-option">
                  <span>{{ model.name }}</span>
                  <el-tag :type="getStatusType(model.status)" size="small">
                    {{ getStatusText(model.status) }}
                  </el-tag>
                </div>
              </el-option>
            </el-select>
          </div>
          
          <div v-if="selectedModel" class="model-info">
            <div class="info-item">
              <span class="label">模型类型：</span>
              <span class="value">{{ getTypeText(selectedModel.type) }}</span>
            </div>
            <div class="info-item">
              <span class="label">算法：</span>
              <span class="value">{{ selectedModel.algorithm }}</span>
            </div>
            <div class="info-item">
              <span class="label">版本：</span>
              <span class="value">v{{ selectedModel.version }}</span>
            </div>
          </div>
        </div>
      </el-card>
    </div>

    <!-- 评估结果 -->
    <div v-if="evaluationResults" class="evaluation-results">
      <!-- 性能指标 -->
      <div class="metrics-section">
        <el-card>
          <template #header>
            <span>性能指标</span>
          </template>
          <el-row :gutter="20">
            <el-col :span="6" v-for="metric in performanceMetrics" :key="metric.key">
              <div class="metric-card">
                <div class="metric-icon" :style="{ color: metric.color }">
                  <el-icon :size="32">
                    <component :is="metric.icon" />
                  </el-icon>
                </div>
                <div class="metric-info">
                  <div class="metric-value">{{ metric.value }}</div>
                  <div class="metric-label">{{ metric.label }}</div>
                </div>
              </div>
            </el-col>
          </el-row>
        </el-card>
      </div>

      <!-- 可视化图表 -->
      <div class="charts-section">
        <el-row :gutter="20">
          <!-- 混淆矩阵 -->
          <el-col :span="12" v-if="selectedModel?.type === 'classification'">
            <el-card>
              <template #header>
                <span>混淆矩阵</span>
              </template>
              <div class="chart-container" ref="confusionMatrixRef" v-loading="loading"></div>
            </el-card>
          </el-col>

          <!-- ROC曲线 -->
          <el-col :span="12" v-if="selectedModel?.type === 'classification'">
            <el-card>
              <template #header>
                <span>ROC曲线</span>
              </template>
              <div class="chart-container" ref="rocCurveRef" v-loading="loading"></div>
            </el-card>
          </el-col>

          <!-- 特征重要性 -->
          <el-col :span="12">
            <el-card>
              <template #header>
                <span>特征重要性</span>
              </template>
              <div class="chart-container" ref="featureImportanceRef" v-loading="loading"></div>
            </el-card>
          </el-col>

          <!-- 预测vs实际 -->
          <el-col :span="12" v-if="selectedModel?.type === 'regression'">
            <el-card>
              <template #header>
                <span>预测值 vs 实际值</span>
              </template>
              <div class="chart-container" ref="predictionScatterRef" v-loading="loading"></div>
            </el-card>
          </el-col>

          <!-- 残差分布 -->
          <el-col :span="12" v-if="selectedModel?.type === 'regression'">
            <el-card>
              <template #header>
                <span>残差分布</span>
              </template>
              <div class="chart-container" ref="residualDistRef" v-loading="loading"></div>
            </el-card>
          </el-col>
        </el-row>
      </div>

      <!-- 详细评估报告 -->
      <div class="report-section">
        <el-card>
          <template #header>
            <span>详细评估报告</span>
          </template>
          <div class="report-content">
            <el-tabs v-model="activeTab">
              <el-tab-pane label="分类报告" name="classification" v-if="selectedModel?.type === 'classification'">
                <el-table :data="classificationReport" stripe>
                  <el-table-column prop="class" label="类别" width="120" />
                  <el-table-column prop="precision" label="精确率" width="100" />
                  <el-table-column prop="recall" label="召回率" width="100" />
                  <el-table-column prop="f1Score" label="F1分数" width="100" />
                  <el-table-column prop="support" label="支持度" width="100" />
                </el-table>
              </el-tab-pane>

              <el-tab-pane label="回归指标" name="regression" v-if="selectedModel?.type === 'regression'">
                <el-descriptions :column="2" border>
                  <el-descriptions-item label="均方误差 (MSE)">{{ regressionMetrics.mse }}</el-descriptions-item>
                  <el-descriptions-item label="均方根误差 (RMSE)">{{ regressionMetrics.rmse }}</el-descriptions-item>
                  <el-descriptions-item label="平均绝对误差 (MAE)">{{ regressionMetrics.mae }}</el-descriptions-item>
                  <el-descriptions-item label="R²分数">{{ regressionMetrics.r2Score }}</el-descriptions-item>
                </el-descriptions>
              </el-tab-pane>

              <el-tab-pane label="交叉验证" name="crossValidation">
                <div class="cv-results">
                  <h4>5折交叉验证结果</h4>
                  <el-table :data="crossValidationResults" stripe>
                    <el-table-column prop="fold" label="折数" width="80" />
                    <el-table-column prop="accuracy" label="准确率" width="100" />
                    <el-table-column prop="precision" label="精确率" width="100" />
                    <el-table-column prop="recall" label="召回率" width="100" />
                    <el-table-column prop="f1Score" label="F1分数" width="100" />
                  </el-table>
                  <div class="cv-summary">
                    <p><strong>平均准确率：</strong>{{ cvSummary.avgAccuracy }}%</p>
                    <p><strong>标准差：</strong>{{ cvSummary.stdDev }}%</p>
                  </div>
                </div>
              </el-tab-pane>
            </el-tabs>
          </div>
        </el-card>
      </div>
    </div>

    <!-- 空状态 -->
    <div v-else class="empty-state">
      <el-empty description="请选择模型并运行评估">
        <el-button type="primary" @click="runEvaluation" :disabled="!selectedModelId">
          开始评估
        </el-button>
      </el-empty>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
import * as echarts from 'echarts'
import {
  VideoPlay, Download, TrendCharts, DataAnalysis,
  CircleCheck, Warning
} from '@element-plus/icons-vue'
import { getModelList, getModelDetail, evaluateModel, getModelMetrics } from '@/api/models'

// 路由实例
const route = useRoute()

// 响应式数据
const loading = ref(false)
const selectedModelId = ref(null)
const evaluationResults = ref(null)
const activeTab = ref('classification')

// 图表引用
const confusionMatrixRef = ref(null)
const rocCurveRef = ref(null)
const featureImportanceRef = ref(null)
const predictionScatterRef = ref(null)
const residualDistRef = ref(null)

// 可用模型列表
const availableModels = ref([])

// 加载可用模型列表
const loadAvailableModels = async () => {
  try {
    console.log('加载可用模型列表...')

    // 只获取训练完成的模型
    const response = await getModelList({
      status: 'trained',
      page_size: 100  // 获取所有训练完成的模型
    })

    if (response && response.success) {
      availableModels.value = response.data.models.map(model => ({
        id: model.id,
        name: model.name,
        type: getModelCategory(model.model_type),  // 转换为通用类型
        model_type: model.model_type,
        status: model.status,
        algorithm: model.algorithm,
        algorithm_display: model.algorithm_display,
        version: model.version,
        accuracy: model.accuracy
      }))

      console.log('加载了', availableModels.value.length, '个可用模型')
    } else {
      console.warn('无法加载模型列表，使用模拟数据')
      // 使用模拟数据作为后备
      availableModels.value = [
        {
          id: 1,
          name: '用户流失预测模型',
          type: 'classification',
          model_type: 'churn_prediction',
          status: 'trained',
          algorithm: 'random_forest',
          algorithm_display: '随机森林',
          version: '2.1',
          accuracy: 0.895
        }
      ]
    }
  } catch (error) {
    console.error('加载模型列表失败:', error)
    ElMessage.error('加载模型列表失败')
  }
}

// 将业务模型类型转换为通用类型
const getModelCategory = (modelType) => {
  const categoryMap = {
    'churn_prediction': 'classification',
    'purchase_prediction': 'classification',
    'fraud_detection': 'classification',
    'recommendation': 'recommendation',
    'user_segmentation': 'clustering',
    'price_optimization': 'regression',
    'inventory_forecast': 'regression',
    'lifetime_value': 'regression',
    'sentiment_analysis': 'classification',
    'conversion_optimization': 'classification'
  }
  return categoryMap[modelType] || 'classification'
}

// 计算属性
const selectedModel = computed(() => {
  return availableModels.value.find(m => m.id === selectedModelId.value)
})

const performanceMetrics = computed(() => {
  if (!evaluationResults.value) return []
  
  const metrics = [
    {
      key: 'accuracy',
      label: '准确率',
      value: '89.5%',
      color: '#67C23A',
      icon: 'CircleCheck'
    },
    {
      key: 'precision',
      label: '精确率',
      value: '87.2%',
      color: '#409EFF',
      icon: 'TrendCharts'
    },
    {
      key: 'recall',
      label: '召回率',
      value: '91.8%',
      color: '#E6A23C',
      icon: 'DataAnalysis'
    },
    {
      key: 'f1Score',
      label: 'F1分数',
      value: '89.4%',
      color: '#F56C6C',
      icon: 'Warning'
    }
  ]
  
  return metrics
})

// 模拟数据
const classificationReport = ref([
  { class: '类别0', precision: 0.88, recall: 0.92, f1Score: 0.90, support: 1250 },
  { class: '类别1', precision: 0.91, recall: 0.85, f1Score: 0.88, support: 980 },
  { class: '类别2', precision: 0.85, recall: 0.89, f1Score: 0.87, support: 1100 }
])

const regressionMetrics = ref({
  mse: 0.025,
  rmse: 0.158,
  mae: 0.112,
  r2Score: 0.892
})

const crossValidationResults = ref([
  { fold: 1, accuracy: 88.5, precision: 86.2, recall: 90.1, f1Score: 88.1 },
  { fold: 2, accuracy: 90.2, precision: 88.7, recall: 91.8, f1Score: 90.2 },
  { fold: 3, accuracy: 89.1, precision: 87.5, recall: 90.6, f1Score: 89.0 },
  { fold: 4, accuracy: 91.0, precision: 89.2, recall: 92.8, f1Score: 91.0 },
  { fold: 5, accuracy: 88.8, precision: 86.9, recall: 90.4, f1Score: 88.6 }
])

const cvSummary = ref({
  avgAccuracy: 89.5,
  stdDev: 1.2
})

// 方法
const handleModelChange = () => {
  evaluationResults.value = null
}

const runEvaluation = async () => {
  if (!selectedModelId.value) {
    ElMessage.warning('请先选择要评估的模型')
    return
  }

  loading.value = true
  try {
    console.log('开始评估模型ID:', selectedModelId.value)

    // 调用真实的评估API
    const response = await evaluateModel(selectedModelId.value)
    console.log('评估API响应:', response)

    if (response && response.success) {
      evaluationResults.value = {
        modelId: selectedModelId.value,
        timestamp: new Date().toLocaleString(),
        metrics: response.data.evaluation_results
      }

      console.log('评估结果:', evaluationResults.value)

      // 渲染图表
      nextTick(() => {
        renderCharts()
      })

      ElMessage.success('模型评估完成')
    } else {
      throw new Error(response?.message || '评估失败')
    }
  } catch (error) {
    console.error('评估失败:', error)
    ElMessage.error(`评估失败: ${error.message}`)
  } finally {
    loading.value = false
  }
}

const exportReport = () => {
  if (!evaluationResults.value) {
    ElMessage.warning('请先运行评估')
    return
  }
  
  ElMessage.success('正在导出评估报告...')
}

const renderCharts = () => {
  if (selectedModel.value?.type === 'classification') {
    renderConfusionMatrix()
    renderROCCurve()
  }
  
  if (selectedModel.value?.type === 'regression') {
    renderPredictionScatter()
    renderResidualDistribution()
  }
  
  renderFeatureImportance()
}

const renderConfusionMatrix = () => {
  if (!confusionMatrixRef.value) return

  const chart = echarts.init(confusionMatrixRef.value)
  
  const data = [
    [0, 0, 850], [0, 1, 45], [0, 2, 25],
    [1, 0, 35], [1, 1, 780], [1, 2, 40],
    [2, 0, 20], [2, 1, 30], [2, 2, 920]
  ]
  
  const option = {
    tooltip: {
      position: 'top',
      formatter: function (params) {
        return `实际: ${params.data[1]}<br/>预测: ${params.data[0]}<br/>数量: ${params.data[2]}`
      }
    },
    grid: {
      height: '50%',
      top: '10%'
    },
    xAxis: {
      type: 'category',
      data: ['类别0', '类别1', '类别2'],
      splitArea: { show: true }
    },
    yAxis: {
      type: 'category',
      data: ['类别0', '类别1', '类别2'],
      splitArea: { show: true }
    },
    visualMap: {
      min: 0,
      max: 1000,
      calculable: true,
      orient: 'horizontal',
      left: 'center',
      bottom: '15%'
    },
    series: [{
      name: '混淆矩阵',
      type: 'heatmap',
      data: data,
      label: {
        show: true
      },
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      }
    }]
  }

  chart.setOption(option)
}

const renderROCCurve = () => {
  if (!rocCurveRef.value) return

  const chart = echarts.init(rocCurveRef.value)
  
  const option = {
    title: {
      text: 'ROC曲线 (AUC = 0.92)',
      left: 'center',
      textStyle: { fontSize: 14 }
    },
    tooltip: {
      trigger: 'axis'
    },
    xAxis: {
      type: 'value',
      name: '假正率 (FPR)',
      min: 0,
      max: 1
    },
    yAxis: {
      type: 'value',
      name: '真正率 (TPR)',
      min: 0,
      max: 1
    },
    series: [
      {
        name: 'ROC曲线',
        type: 'line',
        data: [[0, 0], [0.1, 0.3], [0.2, 0.6], [0.3, 0.8], [0.5, 0.9], [1, 1]],
        smooth: true,
        itemStyle: { color: '#409EFF' }
      },
      {
        name: '随机分类器',
        type: 'line',
        data: [[0, 0], [1, 1]],
        lineStyle: { type: 'dashed' },
        itemStyle: { color: '#909399' }
      }
    ]
  }

  chart.setOption(option)
}

const renderFeatureImportance = () => {
  if (!featureImportanceRef.value) return

  const chart = echarts.init(featureImportanceRef.value)
  
  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' }
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'value'
    },
    yAxis: {
      type: 'category',
      data: ['特征1', '特征2', '特征3', '特征4', '特征5', '特征6']
    },
    series: [{
      name: '重要性',
      type: 'bar',
      data: [0.25, 0.20, 0.18, 0.15, 0.12, 0.10],
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
          { offset: 0, color: '#83bff6' },
          { offset: 0.5, color: '#188df0' },
          { offset: 1, color: '#188df0' }
        ])
      }
    }]
  }

  chart.setOption(option)
}

const renderPredictionScatter = () => {
  if (!predictionScatterRef.value) return

  const chart = echarts.init(predictionScatterRef.value)

  // 生成模拟数据
  const data = []
  for (let i = 0; i < 100; i++) {
    const actual = Math.random() * 100
    const predicted = actual + (Math.random() - 0.5) * 20
    data.push([actual.toFixed(2), predicted.toFixed(2)])
  }
  
  const option = {
    tooltip: {
      trigger: 'item',
      formatter: '实际值: {data[0]}<br/>预测值: {data[1]}'
    },
    xAxis: {
      type: 'value',
      name: '实际值'
    },
    yAxis: {
      type: 'value',
      name: '预测值'
    },
    series: [
      {
        name: '预测vs实际',
        type: 'scatter',
        data: data,
        itemStyle: { color: '#409EFF', opacity: 0.6 }
      },
      {
        name: '理想线',
        type: 'line',
        data: [[0, 0], [100, 100]],
        lineStyle: { type: 'dashed', color: '#F56C6C' },
        symbol: 'none'
      }
    ]
  }

  chart.setOption(option)
}

const renderResidualDistribution = () => {
  if (!residualDistRef.value) return

  const chart = echarts.init(residualDistRef.value)
  
  const option = {
    tooltip: {
      trigger: 'axis'
    },
    xAxis: {
      type: 'category',
      data: ['-3', '-2', '-1', '0', '1', '2', '3'],
      name: '残差'
    },
    yAxis: {
      type: 'value',
      name: '频次'
    },
    series: [{
      name: '残差分布',
      type: 'bar',
      data: [5, 20, 45, 60, 42, 18, 4],
      itemStyle: { color: '#67C23A' }
    }]
  }

  chart.setOption(option)
}

const getStatusType = (status) => {
  const types = {
    training: 'warning',
    completed: 'success',
    deployed: 'primary',
    inactive: 'info'
  }
  return types[status] || 'info'
}

const getStatusText = (status) => {
  const texts = {
    training: '训练中',
    completed: '已完成',
    deployed: '已部署',
    inactive: '已停用'
  }
  return texts[status] || '未知'
}

const getTypeText = (type) => {
  const texts = {
    classification: '分类模型',
    regression: '回归模型',
    clustering: '聚类模型',
    recommendation: '推荐模型'
  }
  return texts[type] || '未知'
}

// 生命周期
onMounted(async () => {
  console.log('模型评估页面初始化...')

  // 加载可用模型列表
  await loadAvailableModels()

  // 如果URL中有模型ID，自动选择
  const modelId = route.params.id
  if (modelId) {
    selectedModelId.value = parseInt(modelId)
    console.log('从URL参数选择模型ID:', modelId)
  }
})
</script>

<style scoped>
.model-evaluation {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: calc(100vh - 120px);
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 20px;
  padding: 20px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.header-content h1 {
  margin: 0 0 8px 0;
  font-size: 24px;
  color: #303133;
}

.header-content p {
  margin: 0;
  color: #606266;
  font-size: 14px;
}

.header-actions {
  display: flex;
  gap: 12px;
}

.model-selection {
  margin-bottom: 20px;
}

.selection-content {
  display: flex;
  gap: 20px;
  align-items: center;
}

.model-option {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.model-info {
  display: flex;
  gap: 20px;
}

.info-item {
  font-size: 14px;
}

.label {
  color: #909399;
}

.value {
  color: #303133;
  font-weight: 500;
}

.evaluation-results {
  margin-bottom: 20px;
}

.metrics-section {
  margin-bottom: 20px;
}

.metric-card {
  display: flex;
  align-items: center;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 8px;
  height: 100px;
}

.metric-icon {
  margin-right: 16px;
}

.metric-info {
  flex: 1;
}

.metric-value {
  font-size: 24px;
  font-weight: bold;
  color: #303133;
  margin-bottom: 4px;
}

.metric-label {
  font-size: 14px;
  color: #606266;
}

.charts-section {
  margin-bottom: 20px;
}

.chart-container {
  height: 300px;
  width: 100%;
}

.report-section {
  margin-bottom: 20px;
}

.report-content {
  padding: 16px 0;
}

.cv-results h4 {
  margin: 0 0 16px 0;
  color: #303133;
}

.cv-summary {
  margin-top: 16px;
  padding: 16px;
  background: #f5f7fa;
  border-radius: 4px;
}

.cv-summary p {
  margin: 4px 0;
  color: #606266;
}

.empty-state {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 400px;
}
</style>
